package com.znyj.cloud.device.task;

import com.znyj.cloud.chain.tcphandler.ClientIdleTimeoutHandler;
import com.znyj.cloud.device.pack.OnlineDeviceInfo;
import io.netty.channel.ChannelHandlerContext;
import io.netty.handler.timeout.IdleStateHandler;
import org.apache.log4j.Logger;

import java.sql.Timestamp;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;

/**
 * Created by gaoliwei02 on 17/6/3.
 */
public class OnlineDeviceInfoMapping {

    private static final Logger logger = Logger.getLogger(OnlineDeviceInfoMapping.class);

    public static final ChannelHandlerContext unGetChannel = null;
//    public static final boolean unGetIsDoing = false;
//    public static final int unGetSendRetry = -1;

    public static final Map<String, OnlineDeviceInfo> deviceInfoMap = new ConcurrentHashMap<>();


    public static void add(String deviceId, ChannelHandlerContext ctx, int timeout) {
        Timestamp timestamp = new Timestamp(System.currentTimeMillis());
        OnlineDeviceInfo onlineDeviceInfo = new OnlineDeviceInfo(deviceId, ctx, timestamp, timeout);
        deviceInfoMap.put(deviceId, onlineDeviceInfo);
        setIdleTime(timeout, ctx);
    }

    public static void updateNewChannel(String deviceId, ChannelHandlerContext ctx) {
        Timestamp timestamp = new Timestamp(System.currentTimeMillis());
        OnlineDeviceInfo onlineDeviceInfo = deviceInfoMap.get(deviceId);
        if (null != onlineDeviceInfo.getCtx()) {
            if (onlineDeviceInfo.getCtx().channel().isActive()) {
                onlineDeviceInfo.getCtx().close();
            }
        }

        onlineDeviceInfo.setCtx(ctx);
        onlineDeviceInfo.setUpdateTime(timestamp);
        setIdleTime(onlineDeviceInfo.getTimeout(), ctx);
    }

    public static void update(String deviceId) {
        Timestamp timestamp = new Timestamp(System.currentTimeMillis());
        OnlineDeviceInfo onlineDeviceInfo = deviceInfoMap.get(deviceId);
        onlineDeviceInfo.setUpdateTime(timestamp);
    }

    public static void changeTimeout(String deviceId,int timeout) {
        OnlineDeviceInfo onlineDeviceInfo = deviceInfoMap.get(deviceId);
        onlineDeviceInfo.setTimeout(timeout);
    }

    public static void removeAndCloseCtx(String deviceId) {
        OnlineDeviceInfo onlineDeviceInfo = deviceInfoMap.get(deviceId);
        if (null != onlineDeviceInfo.getCtx()) {
            if (onlineDeviceInfo.getCtx().channel().isActive()) {
                onlineDeviceInfo.getCtx().close();
            }
        }
        deviceInfoMap.remove(deviceId);
    }

    public static List<OnlineDeviceInfo> getODIByChannel(ChannelHandlerContext ctx) {
        String IP = ctx.channel().remoteAddress().toString();
        List<OnlineDeviceInfo> onlineDeviceInfoList = new ArrayList<>();

        for (Map.Entry<String, OnlineDeviceInfo> entry : deviceInfoMap.entrySet()) {
            String IPX = entry.getValue().getCtx().channel().remoteAddress().toString();
            if (IPX.equals(IP)) {
                onlineDeviceInfoList.add(entry.getValue());
            }
        }

        return onlineDeviceInfoList;
    }

    public static OnlineDeviceInfo getODIByDeviceId(String deviceId) {
        return deviceInfoMap.get(deviceId);
    }

    public static ChannelHandlerContext getChannelByDeviceId(String deviceId) {
        OnlineDeviceInfo info = deviceInfoMap.get(deviceId);
        if (null != info) {
            return info.getCtx();
        }
        return unGetChannel;
    }


    public static void setIdleTime(int idleTime, ChannelHandlerContext ctx) {
        if (ctx.pipeline().names().contains("idleStateHandler")) {
            ctx.pipeline().remove("idleStateHandler");
        }
        if (ctx.pipeline().names().contains("idleEventHandler")) {
            ctx.pipeline().remove("idleEventHandler");
        }
        ctx.pipeline().addFirst("idleStateHandler", new IdleStateHandler(idleTime, 0, 0));
        ctx.pipeline().addAfter("idleStateHandler", "idleEventHandler", new ClientIdleTimeoutHandler());
        logger.info("change idleStateHandler value:{}" + idleTime);
    }

    public static int getOnlineDeviceCount() {
        return deviceInfoMap.size();
    }

    public static boolean contain(String deviceId) {
        return deviceInfoMap.containsKey(deviceId);
    }

//    public static String getStatus(String deviceId) {
//        OnlineDeviceInfo info = deviceInfoMap.get(deviceId);
//        if (null != info) {
//            return info.getStatus();
//        }
//        return OnlineDeviceInfo.DEVICE_STATUS_NORMAL;
//    }
//
//    public static boolean getIsDoing(String deviceId) {
//        OnlineDeviceInfo info = deviceInfoMap.get(deviceId);
//        if (null != info) {
//            return info.getIsDoing();
//        }
//        return unGetIsDoing;
//    }
//
//    public static void setIsDoing(String deviceId, boolean isDoing) {
//        OnlineDeviceInfo info = deviceInfoMap.get(deviceId);
//        if (null != info) {
//            info.setIsDoing(isDoing);
//        }
//    }
//
//    public static int getSendRetry(String deviceId) {
//        OnlineDeviceInfo info = deviceInfoMap.get(deviceId);
//        if (null != info) {
//            return info.getSendRetry();
//        }
//        return unGetSendRetry;
//    }
//
//    public static void setSendRetry(String deviceId, int retry) {
//        OnlineDeviceInfo info = deviceInfoMap.get(deviceId);
//        if (null != info) {
//            info.setSendRetry(retry);
//        }
//    }
}
